<?php
declare (strict_types = 1);

namespace app\admin\controller;
use app\admin\middleware\Auth;
use app\model\ExpressBizIdModel;
use app\model\OrderItemsModel;
use app\model\OrderLogisticsModel;
use app\model\OrdersModel;
use app\model\RedisModel;
use app\model\ShopReturnAddressesModel;
use app\model\ShopsModel;
use app\model\UserModel;
use DateTime;
use DateTimeZone;
use think\App;
use think\facade\Db;

class Orders extends Base {

    protected $middleware = [Auth::class];

    public $cacheKey="order:id:";

    private $aid;

    private $shopsModel;

    private $ordersModel;

    private $orderItemsModel;

    private $req;

    private $shop_id;

    private $userModel;

    private $shopIds;

    private $shopReturnAddressesModel;

    private $orderLogisticsModel;

    private $expressBizIdModel;

    private $page;

    private $limit;

    private $statusList=[
        "all"=>[
            1=>"已支付/待发货",
            2=>"已发货",
            101=>"继续发货",
            3=>"待收货",
            4=>"已完成/待评价",
            5=>"已完成/已评价",
            11=>"商家审核中",
            12=>"商家退款中",
            -12=>"商家已拒绝您的请求",
            -11=>"撤销申请",
            13=>"交易关闭/退款完成",
            -1 => "交易关闭/取消付款",
        ],
        "noSend"=>[
            1=>"已支付/待发货",
        ],
        "haveSend"=>[
            2=>"已发货",
            3=>"待收货",
        ],
        "aftersales"=>[
            -12=>"商家已拒绝您的请求",
            11=>"商家审核中",
            12=>"商家退款中",
        ],
        "success"=>[
            4=>"已完成/待评价",
            5=>"已完成/已评价",
        ],
        "close"=>[
            -1 => "交易关闭/取消付款",
            13=>"交易关闭/退款完成"
        ],
        "continueSend"=>[
            101 => "继续发货"
        ],
    ];



    public function __construct(App $app)
    {
        parent::__construct($app);

        $this->req = request()->param();

        $this->shop_id = isset($this->req['shop_id']) ? $this->req['shop_id'] : "";

        $this->page = isset($this->req['page']) ? $this->req['page'] : 1;

        $this->limit = isset($this->req['limit']) ? $this->req['limit'] : 20;

        $this->shopsModel = new ShopsModel();

        $this->ordersModel = new OrdersModel();

        $this->shopReturnAddressesModel = new ShopReturnAddressesModel();

        $this->orderLogisticsModel = new OrderLogisticsModel();

        $this->orderItemsModel = new OrderItemsModel();

        $this->userModel = new UserModel();

        $this->aid = $this->isLogin();

        $this->shopIds = $this->shopsModel->getShopIds($this->aid);

        $this->expressBizIdModel = new ExpressBizIdModel();
    }


    /*
     * 获取订单状态
     * */
    public function getStatusList(){

        $data = isset($this->req['status']) ? $this->statusList[$this->req['status']]  : $this->statusList['all'];

        return $this->succ($data);
    }

    /*
  * 获取订单详情
  * */
    public function getOrderInfo(){

        if(!isset($this->req["order_id"]) || empty($this->req["order_id"])){
            return  $this->fail("订单号不能为空");
        }


        $orderInfo = $this->ordersModel->getInfo($this->req["order_id"]);

        if($orderInfo["aftersale_status"]  == -1){
            $orderInfo["order_status"] = -11;
        }elseif ($orderInfo["aftersale_status"]  == -2){
            $orderInfo["order_status"] = -12;
        }elseif ($orderInfo["aftersale_status"]  == 1){
            $orderInfo["order_status"] = 11;
        }elseif ($orderInfo["aftersale_status"]  == 2){
            $orderInfo["order_status"] = 12;
        }elseif ($orderInfo["aftersale_status"]  == 3){
            $orderInfo["order_status"] = 13;
        }elseif ($orderInfo["is_all_send"]  == 0){
            $orderInfo["order_status"] = 101;
        }
        // $v['status_info']["order_status_name"]=$this->statusList["all"][$v["order_status"]];

        return $this->succ($orderInfo);
    }

    /*
     * 获取商品列表
     * */
    public function getList(){
        $status = isset($this->req['status']) ? $this->statusList[$this->req['status']]  : $this->statusList['all'];
        $statusWhere=[];
        if($this->req['status'] == "aftersales"){
            $arr =  array_keys($status);
            foreach ($arr as &$v){
                $v %= 10;
            }
            $statusWhere["aftersale_status"] = ["aftersale_status","IN",$arr];
            if(isset($this->req['order_status']) && !empty($this->req['order_status'])){
                $statusWhere["aftersale_status"] = ["aftersale_status","=",( $this->req['order_status'] % 10)];
            }
        }else if($this->req['status'] == "continueSend" || $this->req['order_status'] == 101) {
            $statusWhere["order_status"] = ["order_status", "IN", [1, 2, 3, 4, 5]];
            $statusWhere["aftersale_status"] = ["aftersale_status", "=", 0];
            $statusWhere["is_all_send"] = ["is_all_send", "=", 0];
        }else if($this->req['status'] == "close" && $this->req['order_status'] == 13){
            $statusWhere["order_status"] = ["order_status","=",-1];
            $statusWhere["aftersale_status"] = ["aftersale_status","=",3];
        }else if($this->req['status'] == "close" && $this->req['order_status'] == -1){
            $statusWhere["order_status"] = ["order_status","=",-1];
            $statusWhere["aftersale_status"] = ["aftersale_status","=",0];
        }else if($this->req['status'] == "noSend" || $this->req['status'] == "haveSend" || $this->req['status'] == "success" || $this->req['status'] == "continueSend"){
            $statusWhere["order_status"] = ["order_status","IN",array_keys($status)];
            $statusWhere["aftersale_status"] = ["aftersale_status", "=", 0];
            if(isset($this->req['order_status']) && !empty($this->req['order_status'])){
                $statusWhere["order_status"] = ["order_status","=",$this->req['order_status']];
            }
        } else{
            $statusWhere["order_status"] = ["order_status","IN",array_keys($status)];
            if(isset($this->req['order_status']) && !empty($this->req['order_status'])){
                if(in_array($this->req['order_status'],[11,12,-11,-12,13])){
                    $statusWhere["aftersale_status"] = ["aftersale_status","=",$this->req['order_status'] % 10];
                }elseif ($this->req['order_status'] == 101){
                    $statusWhere["is_all_send"] = ["is_all_send","=",0];
                }else{
                    $statusWhere["order_status"] = ["order_status","=",$this->req['order_status']];
                }
            }
        }


        $where = array_values($statusWhere);

        $where[] = ['o.shop_id','IN',$this->shopIds];


        if(!empty($this->req['product_name'])){
            $where[] = ['it.product_snapshot','like',"%".$this->req['product_name']."%"];
        }


        if(!empty($this->req['order_id'])){
            $where[] = ['o.order_id|o.p_order_id','=',$this->req['order_id']];
        }

        if(!empty($this->req['shop_name'])){
            $where[] = ['s.shop_name','like',"%".$this->req['shop_name']."%"];
        }

        $list = $this->ordersModel->getList($where,$this->page,$this->limit,"o.updated_at","DESC");

        if($list ){
            foreach ($list as &$v){
                if($v["aftersale_status"]  == -1){
                    $v["order_status"] = -11;
                }elseif ($v["aftersale_status"]  == -2){
                    $v["order_status"] = -12;
                }elseif ($v["aftersale_status"]  == 1){
                    $v["order_status"] = 11;
                }elseif ($v["aftersale_status"]  == 2){
                    $v["order_status"] = 12;
                }elseif ($v["aftersale_status"]  == 3){
                    $v["order_status"] = 13;
                }elseif ($v["is_all_send"]  == 0){
                    $v["order_status"] = 101;
                }
               // $v['status_info']["order_status_name"]=$this->statusList["all"][$v["order_status"]];
            }
        }

        $total = $this->ordersModel->getTotal($where);

        $this->succData($total,$list);
    }


    /*
     * 发货接口
     * */
    public function deliver(){

        if(empty($this->req['order_id'])){
            return $this->fail("请选择订单");
        }

        $orderInfo = $this->ordersModel->getInfo($this->req['order_id']);

        if(empty($orderInfo)){
            return $this->fail("订单不存在");
        }

        if($orderInfo['pay_status'] != 1){
            return $this->fail("订单未支付");
        }

        if(empty($this->req['waybill_id'])){
            return $this->fail("请填写运单号");
        }

        if(empty($this->req['delivery_id'])){
            return $this->fail("请选择快递公司");
        }

        if(empty($this->req['delivery_name'])){
            return $this->fail("快递公司名称不能为空");
        }

        if(empty($this->req['sender_address_id'])){
            return $this->fail("请选择发货地址");
        }

        if(empty($this->req['spec_ids'])){
            return $this->fail("请选择发货的商品");
        }

        $senderInfo = $this->shopReturnAddressesModel->getInfo($this->req['sender_address_id']);
        if(empty($senderInfo)){
            return $this->fail("发货地址不存在");
        }

        $returnInfo =[];
        if(isset($this->req['return_address_id']) && !empty($this->req['return_address_id'])){
            $returnInfo = $this->shopReturnAddressesModel->getInfo($this->req['return_address_id']);
            if(empty($returnInfo)){
                return $this->fail("退货地址不存在");
            }
        }

        if($this->orderLogisticsModel->isDeliveryIdHaseUsed($this->req['order_id'],$this->req['waybill_id'])){
            return $this->fail("该单号已经绑定该订单，请勿重复操作");
        }

        $userInfo = $this->userModel->getUserInfoByUid($orderInfo['uid']);
        if(empty($userInfo)){
            return $this->fail("用户不存在");
        }



        //获取订单所有的规格id
        $orderItemsList = $this->orderItemsModel->getOrderItemsList($this->req['order_id']);
        $itemIds = array_unique(array_column($orderItemsList,"spec_id"));

        //获取已发货的规格
        $orderLogisticsInfoList = $this->orderLogisticsModel->getOrderLogisticsInfo($this->req['order_id']);
        $haveSendItemIds =[];
        foreach ($orderLogisticsInfoList as $orderLogisticsInfo){
            $haveSendItemIds = array_merge($haveSendItemIds,$orderLogisticsInfo["spec_ids"]);
        }
        $haveSendItemIds = array_unique(array_merge($haveSendItemIds,$this->req["spec_ids"]));

        //比较发货
        $is_all_send = 0;
        if(array_contains_array($haveSendItemIds,$itemIds)){
            $is_all_send = 1;
        }


        Db::startTrans();

        //更新订单信息
        $deliverRes = $this->ordersModel->deliver($this->req['order_id'],$senderInfo,$returnInfo,$is_all_send);
        $logisticRes = $this->orderLogisticsModel->addOne([
            "order_id" => $this->req['order_id'],
            "delivery_id" => $this->req['delivery_id'],
            "delivery_name" => $this->req['delivery_name'],
            "waybill_id" => $this->req['waybill_id'],
            "wx_openid" => $userInfo["wx_openid"],
            "spec_ids" => json_encode($this->req['spec_ids']),
            "send_type" => "自己联系物流"
        ]);

        if( $deliverRes && $logisticRes){

            $this->delCache($this->req['order_id']);

            Db::commit();

            return $this->succ();

        }else{

            Db::rollback();

            return $this->fail();
        }
    }



    /*
     * 在线发货接口
     * */
    public function onLineDeliver(){

        if(empty($this->req['order_id'])){
            return $this->fail("请选择订单");
        }

        $orderInfo = $this->ordersModel->getInfo($this->req['order_id']);

        if(empty($orderInfo)){
            return $this->fail("订单不存在");
        }

        if($orderInfo['pay_status'] != 1){
            return $this->fail("订单未支付");
        }


        if(empty($this->req['delivery_id'])){
            return $this->fail("请选择快递公司");
        }

        if(empty($this->req['delivery_name'])){
            return $this->fail("快递公司名称不能为空");
        }

        if(empty($this->req['biz_id'])){
            return $this->fail("请选择快递账号");
        }

        if(empty($this->req['sender_address_id'])){
            return $this->fail("请选择发货地址");
        }

        if(empty($this->req['spec_ids'])){
            return $this->fail("请选择发货的商品");
        }

        if(!isset($this->req['service_type'])){
            return $this->fail("请选择服务类型");
        }

        if(!isset($this->req['service_name'])){
            return $this->fail("请选择服务类型");
        }

        if($this->req['delivery_id'] == "SF" &&  (!isset($this->req['expect_time']) || empty($this->req['expect_time']))){
            return $this->fail("顺丰必填预约上门时间");
        }


        if(!empty($this->req['expect_time']) && $this->req['expect_time'] < time()){
            return $this->fail("预约取件时间不能小于当前");
        }


        $bzInfo = $this->expressBizIdModel->getInfo($this->req['biz_id']);

        if($bzInfo["is_cash"]){
            $send_type= "散单现付";
        }else{
            $send_type= "在线下单";
        }

        $senderInfo = $this->shopReturnAddressesModel->getInfo($this->req['sender_address_id']);

        if(empty($senderInfo)){
            return $this->fail("发货地址不存在");
        }

        $returnInfo =[];
        if(isset($this->req['return_address_id']) && !empty($this->req['return_address_id'])){
            $returnInfo = $this->shopReturnAddressesModel->getInfo($this->req['return_address_id']);
            if(empty($returnInfo)){
                return $this->fail("退货地址不存在");
            }
        }


        $userInfo = $this->userModel->getUserInfoByUid($orderInfo['uid']);
        if(empty($userInfo)){
            return $this->fail("用户不存在");
        }


        //获取订单所有的规格id
        $orderItemsList = $this->orderItemsModel->getOrderItemsList($this->req['order_id']);
        $itemIds = array_unique(array_column($orderItemsList,"spec_id"));

        //获取已发货的规格
        $orderLogisticsInfoList = $this->orderLogisticsModel->getOrderLogisticsInfo($this->req['order_id']);
        $haveSendItemIds =[];
        $isFenChaiFlag = false;
        $isAllDeliveredFlag = true;
        foreach ($orderLogisticsInfoList as $orderLogisticsInfo){
            $haveSendItemIds = array_merge($haveSendItemIds,$orderLogisticsInfo["spec_ids"]);
        }
        if(!empty($haveSendItemIds)){
            $isFenChaiFlag = true;//已经存在历史发货记录，即标记为分拆发货
        }

        $haveSendItemIds = array_unique(array_merge($haveSendItemIds,$this->req["spec_ids"]));

        //比较发货
        $is_all_send = 0;
        if(array_contains_array($haveSendItemIds,$itemIds)){
            $is_all_send = 1;
        }
        if(!$isFenChaiFlag && $is_all_send == 0){
            $isFenChaiFlag = true;//不存在历史发货记录，但本次未发货完，也标记为分拆发货
        }

        $isAllDeliveredFlag = $is_all_send == 1 ? true : false;


        if($orderInfo["order_status"] == 3 && $orderInfo["is_all_send"] == 1){
            return $this->fail("该订单已完成发货，不可重复发货");
        }

        $sendData = [];
        $sendData["add_source"] =  0;
        $sendData["order_id"] = $this->req['order_id']."_".mt_rand(100000,999999);
        $sendData["openid"] = $userInfo["wx_openid"];
        $sendData["delivery_id"] = $this->req['delivery_id'];
        $sendData["biz_id"] = $this->req['biz_id'];
        $sendData["custom_remark"] = isset($this->req['remark']) ? $this->req['remark'] : "";
        $sendData["sender"]["name"] = $senderInfo["name"];
        $sendData["sender"]["mobile"] = $senderInfo["mobile"];
        $sendData["sender"]["province"] = $senderInfo["province"];
        $sendData["sender"]["city"] = $senderInfo["city"];
        $sendData["sender"]["area"] = $senderInfo["county"];
        $sendData["sender"]["address"] = $senderInfo["address"];
        $sendData["receiver"]["name"] = $orderInfo["receiver_info"]["name"];
        $sendData["receiver"]["mobile"] = $orderInfo["receiver_info"]["mobile"];
        $sendData["receiver"]["province"] = $orderInfo["receiver_info"]["province"];
        $sendData["receiver"]["city"] = $orderInfo["receiver_info"]["city"];
        $sendData["receiver"]["area"] = $orderInfo["receiver_info"]["county"];
        $sendData["receiver"]["address"] = $orderInfo["receiver_info"]["address"];
        $sendData["shop"]["wxa_path"] ="/view/subPages/OrderDetail/index?orderId=" .  $this->req['order_id'];
        $sendData["shop"]["detail_list"] =[];
        $sendData["cargo"]= [];
        $sendData["cargo"]["count"] = 0;
        $sendData["cargo"]["weight"] = 1;
        $sendData["cargo"]["space_x"] = 1;
        $sendData["cargo"]["space_y"] = 1;
        $sendData["cargo"]["space_z"] = 1;
        $sendData["cargo"]["detail_list"] =[];
        $orderDesc = "";
        foreach ($orderInfo["itemsList"] as $item){
            $detailOne =[];
            $cargoOne=[];
            if(!in_array($item["spec_id"],$this->req["spec_ids"])) continue;
            $detailOne["goods_name"] = $item["product_snapshot"]["product_name"];
            $detailOne["goods_img_url"] = $item["product_snapshot"]["product_thumbnail"];
            $detailOne["goods_desc"] = $item["spec_snapshot"]["spec_name"];
            $sendData["shop"]["detail_list"][] = $detailOne;
            $cargoOne["name"]= $item["product_snapshot"]["product_name"];
            $orderDesc .= $item["product_snapshot"]["product_name"];
            $cargoOne["count"]= 1;
            $sendData["cargo"]["detail_list"] = $cargoOne;
            $sendData["cargo"]["count"] +=  $cargoOne["count"];
        }

        if(isset($this->req["insured_value"]) && $this->req["insured_value"] > 0){
            $sendData["insured"]["use_insured"] = 1;
            $sendData["insured"]["insured_value"] = $this->req["insured_value"] * 100;
        }else{
            $sendData["insured"]["use_insured"] = 0;
            $sendData["insured"]["insured_value"] = 0;
        }


        $sendData["service"]["service_type"] = $this->req["service_type"];
        $sendData["service"]["service_name"] = $this->req["service_name"];
        if(!empty($this->req['expect_time']) ){
            $sendData["expect_time"] = $this->req['expect_time'];
        }

        $response = createExpressOrder($sendData);


        if ($response->getStatusCode() == 200) {
            $wayillResponse = $response->getBody()->getContents();

            addWxPayLog("create_express_order.txt",json_encode(["req"=>$sendData,"res"=>$wayillResponse],256));

            $wayillResponse = json_decode($wayillResponse, true);

            if($wayillResponse['errcode'] != 0){
                return $this->fail("操作失败:".$wayillResponse["errmsg"]);
            }

        } else {

            addWxPayLog("create_express_order_err.txt","请求腾讯快递生成面单接口失败：". $response->getBody()->getContents());

            return $this->fail("请求腾讯快递生成面单接口失败：". $response->getBody()->getContents());
        }


        //录单信息传入
        $ludanData =[];
        $ludanData["order_key"]["order_number_type"] = 1;
        $ludanData["order_key"]["transaction_id"] = $orderInfo["wx_transaction_id"];
        $ludanData["order_key"]["mchid"] = $orderInfo["wx_pay_info"]["mch_id"];
        $ludanData["order_key"]["out_trade_no"] = $orderInfo["wx_pay_info"]["out_trade_no"];
        $ludanData["delivery_mode"] = $isFenChaiFlag ? 1 : 2;
        $ludanData["is_all_delivered"] = $isAllDeliveredFlag;

        //is_all_delivered
        $ludanData["logistics_type"] = 1;
        $ludanData["shipping_list"][] =[
            "tracking_no"=>$wayillResponse['waybill_id'],
            "express_company"=>$this->req['delivery_id'],
            "item_desc"=>mb_substr($orderDesc,0,100)."...",
        ];

        // 创建 DateTime 对象，设置时区为东八区（北京时间）
        $dateTime = new DateTime('now', new DateTimeZone('Asia/Shanghai'));
        // 格式化时间为 RFC 3339 格式
        $formattedTime = $dateTime->format('Y-m-d\TH:i:s.vP');
        $ludanData["upload_time"] = $formattedTime;
        $ludanData["payer"]["openid"] = $userInfo["wx_openid"];

        $response = sendGoodsForLuDan($ludanData);

        if ($response->getStatusCode() == 200) {
            $ludanResponse = $response->getBody()->getContents();
            addWxPayLog("send_goods_for_ludan.txt",json_encode(["req"=>$ludanData,"res"=>$ludanResponse],256));
            $ludanResponse = json_decode($ludanResponse, true);
            if($ludanResponse['errcode'] != 0){
                return $this->fail("操作失败:".$ludanResponse["errmsg"]);
            }

        } else {

            addWxPayLog("send_goods_for_ludan_err.txt","请求腾讯快递生成面单接口失败：". $response->getBody()->getContents());

            return $this->fail("请求腾讯面单录入接口失败：". $response->getBody()->getContents());
        }

        Db::startTrans();


        //更新订单信息
        $deliverRes = $this->ordersModel->deliver($this->req['order_id'],$senderInfo,$returnInfo,$is_all_send);
        $logisticRes = $this->orderLogisticsModel->addOne([
            "order_id" => $this->req['order_id'],
            "delivery_id" => $this->req['delivery_id'],
            "delivery_name" => $this->req['delivery_name'],
            "waybill_id" => $wayillResponse['waybill_id'],
            "wx_openid" => $userInfo["wx_openid"],
            "spec_ids" => json_encode($this->req['spec_ids']),
            "wx_request"=>json_encode($sendData,256),
            "wx_response"=>json_encode($wayillResponse,256),
            "send_type"=>$send_type
        ]);

        if( $deliverRes && $logisticRes){

            $this->delCache($this->req['order_id']);

            Db::commit();

            return $this->succ("下单成功，单号:".$wayillResponse['waybill_id']);

        }else{

            Db::rollback();

            return $this->fail();
        }
    }




    /*
     * 修改运单
     * */
    public function editWaybill(){

        if(empty($this->req['logistics_id'])){
            return $this->fail("logistics_id 不能为空");
        }

        if(empty($this->req['waybill_id'])){
            return $this->fail("请填写运单号");
        }

        if(empty($this->req['delivery_id'])){
            return $this->fail("请选择快递公司");
        }

        if(empty($this->req['delivery_name'])){
            return $this->fail("快递公司名称不能为空");
        }

        $logisticRes = $this->orderLogisticsModel->updateOne($this->req['logistics_id'], [
            "delivery_id" => $this->req['delivery_id'],
            "delivery_name" => $this->req['delivery_name'],
            "waybill_id" => $this->req['waybill_id'],
            "logistics_status" => 0,
        ]);

        if(  $logisticRes){

            Db::commit();

            return $this->succ();

        }else{

            Db::rollback();

            return $this->fail();

        }
    }



    /*
     * 修改发货人
     *
     * */
    public function editSender(){

        if(empty($this->req['order_id'])){
            return $this->fail("请选择订单");
        }

        $orderInfo = $this->ordersModel->getInfo($this->req['order_id']);

        if(empty($orderInfo)){
            return $this->fail("订单不存在");
        }


        if(empty($this->req['sender_address_id'])){
            return $this->fail("请选择发货地址");
        }

        $senderInfo = $this->shopReturnAddressesModel->getInfo($this->req['sender_address_id']);
        if(empty($senderInfo)){
            return $this->fail("发货地址不存在");
        }

        //更新订单信息
        $res = $this->ordersModel->editSender($this->req['order_id'],$senderInfo);

        $this->delCache($this->req['order_id']);

        return $this->succ();
    }

    /*
     * 修改退货地址
     * */
    public function editReturn(){
        if(empty($this->req['order_id'])){
            return $this->fail("请选择订单");
        }

        $orderInfo = $this->ordersModel->getInfo($this->req['order_id']);

        if(empty($orderInfo)){
            return $this->fail("订单不存在");
        }


        if(empty($this->req['return_address_id'])){
            return $this->fail("请选择退货地址");
        }

        $returnInfo = $this->shopReturnAddressesModel->getInfo($this->req['return_address_id']);
        if(empty($returnInfo)){
            return $this->fail("退货地址不存在");
        }

        //更新订单信息
        $res = $this->ordersModel->editReturn($this->req['order_id'],$returnInfo);

        $this->delCache($this->req['order_id']);

        return $this->succ();
    }



    public function delCache($id)
    {
        $redisModel = new RedisModel();

        return $redisModel->delete($this->cacheKey.$id);
    }


    public function delAllCache()
    {
        $redisModel = new RedisModel();

        return $redisModel->deleteAll($this->cacheKey);
    }

}
